#include "dirStack.h"


_dirStack_t* _dirStack_create() {
    _dirStack_t* s = (_dirStack_t*)calloc(1, sizeof(_dirStack_t));
    if (!s) {
        perror("_dirStack_create calloc failed");
        return NULL;
    }
    // 初始化栈
    s->_top = -1;
    return s;
}
void _dirStack_initSlience(_dirStack_t *s)
{
	bzero(s->_stack, 1024 * sizeof(char *));
	s->_top = -1;
}

int _dirStack_init(_dirStack_t **s) { // 传入二级指针
    *s = (_dirStack_t*)calloc(1, sizeof(_dirStack_t));
    if (!*s) {
        perror("calloc for dirStack failed");
        return -1; // 返回错误码
    }
    (*s)->_top = -1;
    memset((*s)->_stack, 0, sizeof((*s)->_stack));
    return 0;
}
bool _dirStack_empty(_dirStack_t *s)
{
	return s->_top == -1;
}

int _dirStack_push(_dirStack_t* s, char* token)
{
	if (s->_top >= 1023) {
		fprintf(stderr, "Stack overflow\n");
		return 1;
	}

	// 分配新内存（+1 确保有 \0 结尾）
	char* tmp = (char*)calloc(strlen(token) + 1, sizeof(char));
	if (!tmp) {
		perror("_dirStack_push calloc failed");
		return 1;
	}

	strcpy(tmp, token);
	s->_stack[++s->_top] = tmp;
	return 0;
}

int _dirStack_pop(_dirStack_t* s)
{
	if (_dirStack_empty(s)) {
		fprintf(stderr, "Pop from empty stack.\n");
		return 1;
	}
	free(s->_stack[s->_top]);
	s->_stack[s->_top] = NULL;
	--s->_top;
	return 0;
}

char *_dirStack_top(_dirStack_t *s)
{
	if (_dirStack_empty(s)) {
		fprintf(stderr, "Get top from empty stack.\n");
		return NULL;
	}
	return s->_stack[s->_top];
}
// 复制栈（确保不共享指针）
int _dirStack_copy(_dirStack_t *dest, const _dirStack_t *src)
{
	dest->_top = src->_top;
	for (int i = 0; i <= src->_top; ++i) {
		if (src->_stack[i]) {
			dest->_stack[i] = strdup(src->_stack[i]);
			if (!dest->_stack[i]) {
				perror("_dirStack_copy strdup failed");
				return 1;
			}
		} else {
			dest->_stack[i] = NULL;
		}
	}
	return 0;
}

char* _dirStack_getDir(_dirStack_t* s) {
    char* str = (char*)calloc(4096, sizeof(char));
    if (!str) return NULL;
    
    for (int i = 0; i <= s->_top; ++i) {
        strcat(str, s->_stack[i]);
        strcat(str, "/");
    }
    return str;
}
void _dirStack_destroy(_dirStack_t **s)
{
	if (s && *s) {
		free(*s);
		*s = NULL; // 避免野指针
	}
}

char *_dirStack_traverseToString(_dirStack_t *s)
{
	if (s == NULL || _dirStack_empty(s)) {
		return strdup(""); // 返回空字符串
	}


	int n = s->_top + 1; // 栈中元素个数
	int totalLength = 0;

	// 计算总长度
	for (int i = 0; i < n; i++) {
		if (s->_stack[i] == NULL) {
			return strdup("");
		}
		totalLength += strlen(s->_stack[i]);
	}
	totalLength += n - 1; // 分隔符数目
	totalLength += 1; // 终止字符

	char *result = (char *)malloc(totalLength);
	if (result == NULL) {
		return NULL;
	}
	result[0] = '\0'; // 初始化为空字符串
	// 拼接字符串
	for (int i = 0; i < n; i++) {
		if (i > 0) {
			strcat(result, "/"); // 添加分隔符
		}
		strcat(result, s->_stack[i]);
	}
	return result;
}

/* void test_dirStack() { */
/*     _dirStack_t stack; */
/*     _dirStack_init(&stack); */

/*     printf("Test: Initialize Stack\n"); */
/*     printf("Expected: Stack should be empty\n"); */
/*     printf("Result: %s\n", _dirStack_empty(&stack) ? "Empty" : "Not Empty"); */

/*     printf("\nTest: Push elements onto Stack\n"); */
/*     _dirStack_push(&stack, "folder1"); */
/*     _dirStack_push(&stack, "folder2"); */
/*     _dirStack_push(&stack, "folder3"); */

/*     printf("Expected: Stack should not be empty\n"); */
/*     printf("Result: %s\n", _dirStack_empty(&stack) ? "Empty" : "Not Empty"); */

/*     printf("\nTest: Get top element\n"); */
/*     printf("Expected: folder3\n"); */
/*     printf("Result: %s\n", _dirStack_top(&stack)); */

/*     printf("\nTest: Pop top element\n"); */
/*     _dirStack_pop(&stack); */
/*     printf("Expected: folder2\n"); */
/*     printf("Result: %s\n", _dirStack_top(&stack)); */

/*     printf("\nTest: Pop remaining elements\n"); */
/*     _dirStack_pop(&stack); */
/*     _dirStack_pop(&stack); */

/*     printf("Expected: Stack should be empty\n"); */
/*     printf("Result: %s\n", _dirStack_empty(&stack) ? "Empty" : "Not Empty"); */

/*     printf("\nTest: Pop from empty stack\n"); */
/*     printf("Expected: Error message\n"); */
/*     _dirStack_pop(&stack); */
/* } */

/* int main() { */
/*     test_dirStack(); */
/*     return 0; */
/* } */
